In [1]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio as psnr
In [23]:
img1 = cv2.imread('color.jpg')
img1_rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
img2 = cv2.imread('bright.jpg')
img2_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
img3 = cv2.imread('gd.jpg')
img3_rgb = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(img1_rgb)
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(img2_rgb)
plt.axis('off')
plt.tight_layout()
plt.subplot(1, 3, 3)
plt.imshow(img3_rgb)
plt.axis('off')
plt.tight_layout()
plt.show()
In [3]:
kernel1 = np.array([
[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]
])
kernel2 = np.array([
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
])
kernel3 = np.ones((5, 5), np.float32) / 25
kernel4 = np.array([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
]) / 9
kernel5 = np.array([
[1, 4, 6, 4, 1],
[4, 16, 24, 16, 4],
[6, 24, 36, 24, 6],
[4, 16, 24, 16, 4],
[1, 4, 6, 4, 1]]) / 256
kernels = [kernel1, kernel2, kernel3, kernel4, kernel5]
kernel_names = ['Sharpen 1', 'Sharpen 2', 'Blur 1', 'Blur 2', 'Gaussian Blur']
In [25]:
plt.figure(figsize=(15, 12))
for i, (kernel, name) in enumerate(zip(kernels, kernel_names)):
result1 = cv2.filter2D(img1_rgb, -1, kernel)
result2 = cv2.filter2D(img2_rgb, -1, kernel)
result3 = cv2.filter2D(img3_rgb, -1, kernel)
plt.subplot(5, 3, 3*i+1)
plt.imshow(result1)
plt.title(name)
plt.axis('off')
plt.subplot(5, 3, 3*i+2)
plt.imshow(result2)
plt.title(name)
plt.axis('off')
plt.subplot(5, 3, 3*i+3)
plt.imshow(result3)
plt.title(name)
plt.axis('off')
plt.tight_layout()
plt.show()
In [30]:
noise1 = np.random.normal(0, 5, img1_rgb.shape).astype(np.uint8)
noisy1 = cv2.add(img1_rgb, noise1)
noise2 = np.random.normal(0, 5, img2_rgb.shape).astype(np.uint8)
noisy2 = cv2.add(img2_rgb, noise2)
noise3 = np.random.normal(0, 5, img3_rgb.shape).astype(np.uint8)
noisy3 = cv2.add(img3_rgb, noise3)
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(noisy1)
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(noisy2)
plt.axis('off')
plt.tight_layout()
plt.subplot(1, 3, 3)
plt.imshow(noisy3)
plt.axis('off')
plt.tight_layout()
plt.show()
In [36]:
def apply_filters(img):
results = {}
# Blur
results['Mean'] = cv2.blur(img, (5, 5))
results['Gaussian'] = cv2.GaussianBlur(img, (5, 5), 0)
results['Median'] = cv2.medianBlur(img, 5)
results['Bilateral'] = cv2.bilateralFilter(img, 9, 75, 75)
# Sobel
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel_xy = cv2.Sobel(gray, cv2.CV_64F, 1, 1, ksize=3)
sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2)
results['Sobel X'] = cv2.cvtColor(np.uint8(np.abs(sobel_x)), cv2.COLOR_GRAY2RGB)
results['Sobel Y'] = cv2.cvtColor(np.uint8(np.abs(sobel_y)), cv2.COLOR_GRAY2RGB)
results['Sobel XY'] = cv2.cvtColor(np.uint8(np.abs(sobel_xy)), cv2.COLOR_GRAY2RGB)
results['Sobel Combined'] = cv2.cvtColor(np.uint8(sobel_combined), cv2.COLOR_GRAY2RGB)
# Laplacian
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
results['Laplacian'] = cv2.cvtColor(np.uint8(np.abs(laplacian)), cv2.COLOR_GRAY2RGB)
# Non-Local Means
nlm = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
results['Non-Local Means'] = nlm
# Box Filter
results['Box Filter'] = cv2.boxFilter(img, -1, (9, 9))
# Canny
canny = cv2.Canny(gray, 100, 200)
results['Canny'] = cv2.cvtColor(canny, cv2.COLOR_GRAY2RGB)
# Errosion
kernel = np.ones((5, 5), np.uint8)
results['Erosion'] = cv2.erode(img, kernel, iterations=1)
return results
In [37]:
filtered1 = apply_filters(noisy1)
filtered2 = apply_filters(noisy2)
filtered3 = apply_filters(noisy3)
filter_names = list(filtered1.keys())
plt.figure(figsize=(20, 30))
for i, name in enumerate(filter_names):
plt.subplot(len(filter_names), 3, 3*i+1)
plt.imshow(filtered1[name])
plt.title(name)
plt.axis('off')
plt.subplot(len(filter_names), 3, 3*i+2)
plt.imshow(filtered2[name])
plt.title(name)
plt.axis('off')
plt.subplot(len(filter_names), 3, 3*i+3)
plt.imshow(filtered3[name])
plt.title(name)
plt.axis('off')
plt.tight_layout()
plt.show()
In [44]:
def calculate_metrics(original, processed):
psnr_val = psnr(original, processed)
ssim_val = ssim(original, processed, multichannel=True, channel_axis=2)
return psnr_val, ssim_val
results1 = {}
results2 = {}
results3 = {}
for name in filter_names:
psnr1, ssim1 = calculate_metrics(img1_rgb, filtered1[name])
psnr2, ssim2 = calculate_metrics(img2_rgb, filtered2[name])
psnr3, ssim3 = calculate_metrics(img3_rgb, filtered3[name])
results1[name] = {'PSNR': psnr1, 'SSIM': ssim1}
results2[name] = {'PSNR': psnr2, 'SSIM': ssim2}
results3[name] = {'PSNR': psnr3, 'SSIM': ssim3}
In [50]:
import pandas as pd
from IPython.display import display
import warnings
warnings.filterwarnings("ignore")
data = []
for name in filter_names:
row = [
results1[name]['PSNR'], results1[name]['SSIM'],
results2[name]['PSNR'], results2[name]['SSIM'],
results3[name]['PSNR'], results3[name]['SSIM']
]
data.append(row)
df = pd.DataFrame(data, index=filter_names,
columns=['Image 1 PSNR', 'Image 1 SSIM',
'Image 2 PSNR', 'Image 2 SSIM',
'Image 3 PSNR', 'Image 3 SSIM'])
def psnr_color(val):
norm_val = min(max(val / 50, 0), 1)
return f'background-color: rgba({255*(1-norm_val)}, {0}, {255*norm_val}, 0.7)'
def ssim_color(val):
norm_val = min(max((val + 1) / 2, 0), 1)
return f'background-color: rgba({255*(1-norm_val)}, {0}, {255*norm_val}, 0.7)'
styled_df = df.style.format("{:.2f}")
for col in [0, 2, 4]:
styled_df = styled_df.applymap(psnr_color, subset=df.columns[col])
for col in [1, 3, 5]:
styled_df = styled_df.applymap(ssim_color, subset=df.columns[col])
display(styled_df)
| Â | Image 1 PSNR | Image 1 SSIM | Image 2 PSNR | Image 2 SSIM | Image 3 PSNR | Image 3 SSIM |
|---|---|---|---|---|---|---|
| Mean | 10.47 | 0.32 | 15.91 | 0.67 | 12.05 | 0.42 |
| Gaussian | 10.34 | 0.31 | 15.95 | 0.65 | 11.94 | 0.42 |
| Median | 9.96 | 0.19 | 14.83 | 0.44 | 11.27 | 0.31 |
| Bilateral | 7.52 | 0.17 | 13.90 | 0.58 | 9.39 | 0.33 |
| Sobel X | 7.57 | -0.00 | 3.55 | -0.02 | 5.10 | -0.01 |
| Sobel Y | 7.59 | -0.00 | 3.55 | -0.02 | 5.14 | -0.00 |
| Sobel XY | 7.67 | -0.00 | 3.02 | -0.01 | 5.05 | -0.00 |
| Sobel Combined | 7.40 | 0.00 | 4.22 | -0.02 | 5.23 | 0.00 |
| Laplacian | 7.55 | -0.00 | 3.75 | -0.03 | 5.11 | -0.02 |
| Non-Local Means | 7.39 | 0.12 | 14.12 | 0.56 | 9.19 | 0.32 |
| Box Filter | 10.54 | 0.32 | 15.65 | 0.65 | 12.11 | 0.42 |
| Canny | 4.86 | -0.00 | 2.40 | -0.01 | 3.58 | -0.00 |
| Erosion | 19.68 | 0.53 | 17.05 | 0.71 | 17.76 | 0.51 |
In [53]:
plt.figure(figsize=(16, 8))
plt.subplot(3, 4, 1)
plt.imshow(img1_rgb)
plt.title('Original')
plt.axis('off')
plt.subplot(3, 4, 2)
plt.imshow(noisy1)
plt.title('Noisy')
plt.axis('off')
plt.subplot(3, 4, 3)
plt.imshow(filtered1["Erosion"])
plt.title(f'Best: Erosion')
plt.axis('off')
plt.subplot(3, 4, 4)
plt.text(0.1, 0.7, f'PSNR: {results1["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results1["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')
plt.subplot(3, 4, 5)
plt.imshow(img2_rgb)
plt.title('Original')
plt.axis('off')
plt.subplot(3, 4, 6)
plt.imshow(noisy2)
plt.title('Noisy')
plt.axis('off')
plt.subplot(3, 4, 7)
plt.imshow(filtered2["Erosion"])
plt.title('Best: Erosion')
plt.axis('off')
plt.subplot(3, 4, 8)
plt.text(0.1, 0.7, f'PSNR: {results2["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results2["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')
plt.subplot(3, 4, 9)
plt.imshow(img3_rgb)
plt.title('Original')
plt.axis('off')
plt.subplot(3, 4, 10)
plt.imshow(noisy3)
plt.title('Noisy')
plt.axis('off')
plt.subplot(3, 4, 11)
plt.imshow(filtered3["Erosion"])
plt.title('Best: Erosion')
plt.axis('off')
plt.subplot(3, 4, 12)
plt.text(0.1, 0.7, f'PSNR: {results3["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results3["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')
plt.tight_layout()
plt.show()
overall erosion was the best for the noisy image recovery.
noise reduction filters like mean, gaussian, box filters had poor to fair performance.
the edge detection techniques performed the worse due to them only detecting the edges and loosing all other data
image base observations were that overall image 2 with the bird was the best followed by image 3 and then image 1.